/**
 * 
 */
package com.vivid.dynamics.oknow.model;

import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author jason
 * created at:: Jul 27, 2011 5:14:35 PM
 */
public class Bookmark {
	private int id;
	//private int userId;
	private String name;
	private String descr;
	private java.sql.Timestamp createDate;
	private int totalRates;
	private int numRates;
	private double averageRates;
	private int totalStars;
	private int numStars;
	private double averageStars;
	private String metaTags;
	private boolean active=true;
	private String uri;
	private User user;
	// set of permission bounded to this bookmark
	private Set<Permission> permissions;
	
	/**
	 * ctor.
	 */
	protected Bookmark() {}
	
	/**
	 * ctor.
	 * @param name
	 * @param descr
	 * @param createDate
	 * @param totalRates
	 * @param numRates
	 * @param averageRates
	 * @param totalStars
	 * @param numStars
	 * @param averageStars
	 * @param metaTags
	 * @param active
	 */
	public Bookmark(String name, String descr, Timestamp createDate,
		int totalRates, int numRates, double averageRates, int totalStars,
		int numStars, double averageStars, String metaTags, boolean active, String uri) {
		super();
		//this.userId = userId;
		this.name = name;
		this.descr = descr;
		this.createDate = createDate;
		this.totalRates = totalRates;
		this.numRates = numRates;
		this.averageRates = averageRates;
		this.totalStars = totalStars;
		this.numStars = numStars;
		this.averageStars = averageStars;
		this.metaTags = metaTags;
		this.active=active;
		this.uri=uri;
	}

	/**
	 * 	{@inheritDoc}
	 */
	@Override
	public String toString() {
		return "Bookmark [id=" + id + ", name=" + name + ", descr=" + descr
			+ ", createDate=" + createDate + ", totalRates=" + totalRates
			+ ", numRates=" + numRates + ", averageRates=" + averageRates
			+ ", totalStars=" + totalStars + ", numStars=" + numStars
			+ ", averageStars=" + averageStars + ", metaTags=" + metaTags
			+ ", active=" + active + ", uri=" + uri + "]";
	}

	/**
	 * <b>PS</b>. a MUST for hibernate entities, or you will have problems 
	 * during association methods; simply you can't remove / update the correct
	 * logical Entity in your collections<p/>
	 * {@inheritDoc}
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		/*
		result = prime * result + (active ? 1231 : 1237);
		long temp;
		temp = Double.doubleToLongBits(averageRates);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(averageStars);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		result = prime * result
				+ ((createDate == null) ? 0 : createDate.hashCode());
		result = prime * result + ((descr == null) ? 0 : descr.hashCode());		
		result = prime * result
				+ ((metaTags == null) ? 0 : metaTags.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + numRates;
		result = prime * result + numStars;
		result = prime * result + totalRates;
		result = prime * result + totalStars;
		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
		*/
		return result;
	}
	
	/**
	 * <b>PS</b>. a MUST for hibernate entities, or you will have problems 
	 * during association methods; simply you can't remove / update the correct
	 * logical Entity in your collections<p/>
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Bookmark)) {
			//if (getClass() != obj.getClass())
			return false;
		}
		
		Bookmark other = (Bookmark) obj;
		if (id != other.id)
			return false;
		
		if (active != other.active)
			return false;
		if (Double.doubleToLongBits(averageRates) != Double
				.doubleToLongBits(other.averageRates))
			return false;
		if (Double.doubleToLongBits(averageStars) != Double
				.doubleToLongBits(other.averageStars))
			return false;
		if (createDate == null) {
			if (other.createDate != null)
				return false;
		} else if (!createDate.equals(other.createDate))
			return false;
		if (descr == null) {
			if (other.descr != null)
				return false;
		} else if (!descr.equals(other.descr))
			return false;
		if (metaTags == null) {
			if (other.metaTags != null)
				return false;
		} else if (!metaTags.equals(other.metaTags))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (numRates != other.numRates)
			return false;
		if (numStars != other.numStars)
			return false;
		if (totalRates != other.totalRates)
			return false;
		if (totalStars != other.totalStars)
			return false;
		if (uri == null) {
			if (other.uri != null)
				return false;
		} else if (!uri.equals(other.uri))
			return false;
		
		return true;
	}
	
	/* ********************** */
	/* *  accessor/mutator  * */
	/* ********************** */
	
	/*
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:20:44 PM
	 *
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}*/

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:20:57 PM
	 */
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:01 PM
	 */
	public String getDescr() {
		return descr;
	}
	public void setDescr(String descr) {
		this.descr = descr;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:06 PM
	 */
	public java.sql.Timestamp getCreateDate() {
		return createDate;
	}
	public void setCreateDate(java.sql.Timestamp createDate) {
		this.createDate = createDate;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:11 PM
	 */
	public int getTotalRates() {
		return totalRates;
	}
	public void setTotalRates(int totalRates) {
		this.totalRates = totalRates;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:16 PM
	 */
	public int getNumRates() {
		return numRates;
	}
	public void setNumRates(int numRates) {
		this.numRates = numRates;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:22 PM
	 */
	public double getAverageRates() {
		return averageRates;
	}
	public void setAverageRates(double averageRates) {
		this.averageRates = averageRates;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:28 PM
	 */
	public int getTotalStars() {
		return totalStars;
	}
	public void setTotalStars(int totalStars) {
		this.totalStars = totalStars;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:33 PM
	 */
	public int getNumStars() {
		return numStars;
	}
	public void setNumStars(int numStars) {
		this.numStars = numStars;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:38 PM
	 */
	public double getAverageStars() {
		return averageStars;
	}
	public void setAverageStars(double averageStars) {
		this.averageStars = averageStars;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:43 PM
	 */
	public String getMetaTags() {
		return metaTags;
	}
	public void setMetaTags(String metaTags) {
		this.metaTags = metaTags;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 27, 2011  5:21:48 PM
	 */
	public int getId() {
		return id;
	}
	protected void setId(int pId) {
		this.id=pId;
	}
	
	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Aug 4, 2011  12:15:09 PM
	 */
	public boolean isActive() {
		return active;
	}
	public void setActive(boolean active) {
		this.active = active;
	}
	
	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Aug 4, 2011  3:08:48 PM
	 */
	public String getUri() {
		return uri;
	}
	public void setUri(String uri) {
		this.uri = uri;
	}

	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 28, 2011  11:30:42 AM
	 */
	public User getUser() {
		return user;
	}
	protected void setUser(User user) {
		this.user = user;
	}
	/**
	 * 
	 * @return
	 * @author jason
	 * created at:: Jul 28, 2011  11:32:07 AM
	 */
	public Set<Permission> getPermissions() {
		if (this.permissions==null) {
			this.permissions=new HashSet<Permission>();
		}
		return permissions;
	}
	protected void setPermissions(Set<Permission> permissions) {
		this.permissions = permissions;
	}
	
	/* ************************* */
	/* *   associate methods   * */
	/* ************************* */
		
	/**
	 * convenient method to add a Permission to both ends of the relation.
	 * <ul>
	 * 	<li>Bookmark {owner}</li>
	 * 	<li>Permission</li>
	 * </ul>
	 * @param pPer
	 * @author jason
	 * created at:: Aug 5, 2011  2:59:33 PM
	 */
	public void addPermission(final Permission pPer) {
		if (pPer!=null) {
			// update "this"
			this.getPermissions().add(pPer);
			
			// update "pPer"
			pPer.getBookmarks().add(this);
		}
	}
	
	/**
	 * convenient method to remove a Permission to both ends of the relation.
	 * <ul>
	 * 	<li>Bookmark {owner}</li>
	 * 	<li>Permission</li>
	 * </ul>
	 * @param pPer
	 * @author jason
	 * created at:: Aug 5, 2011  3:27:08 PM
	 */
	public void removePermission(final Permission pPer) {
		if (pPer!=null) {
			// update "this"
			this.getPermissions().remove(pPer);
			// update "pPer"
			pPer.getBookmarks().remove(this);
		}
	}
	
}
